home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 11 / PC World Interactive 11.iso / share / multimed / effect / Application Files / ComApplication.c next >
Encoding:
C/C++ Source or Header  |  1998-03-12  |  15.6 KB  |  576 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic QuickTime movie display and control.
  6. //                This file is used for BOTH MacOS and Windows.
  7. //
  8. //    Written by:    Tim Monroe
  9. //                Based (heavily!) on the MovieShell code written by Apple DTS.
  10. //
  11. //    Copyright:    ⌐ 1994-1997 by Apple Computer, Inc., all rights reserved.
  12. //
  13. //    Change History (most recent first):
  14. //
  15. //       <13>         02/28/98    rtm        reworked DoApplicationEventLoopAction
  16. //       <12>         11/21/97    rtm        added code to DoApplicationEventLoopAction to handle effects dialog events
  17. //       <11>         11/06/97    rtm        removed QTVR support; added support for MakeEffectMovie routines;
  18. //                                    added AppleEvent support
  19. //       <10>         10/23/97    rtm        moved InitializeQTVR to InitApplication, TerminateQTVR to StopApplication
  20. //       <9>         10/13/97    rtm        reworked HandleApplicationMenu to use menu identifiers
  21. //       <8>         09/11/97    rtm        merged MacApplication.c and WinApplication.c into ComApplication.c
  22. //       <7>         08/21/97    rtm        first file for Windows; based on MacApplication.c for Mac sample code
  23. //       <6>         06/04/97    rtm        removed call to QTVRUtils_IsQTVRMovie in InitApplicationWindowObject
  24. //       <5>         02/06/97    rtm        fixed window resizing code
  25. //       <4>         12/05/96    rtm        added hooks into MacFramework.c: StopApplication, InitApplicationWindowObject
  26. //       <3>         12/02/96    rtm        added cursor updating to DoIdle
  27. //       <2>         11/27/96    rtm        conversion to personal coding style; added preliminary QTVR support
  28. //       <1>         12/21/94    khs        first file
  29. //       
  30. //////////
  31.  
  32. // header files
  33.  
  34. #include "ComApplication.h"
  35. #include "MakeEffectMovie.h"
  36.  
  37. // global variables for Macintosh code
  38. #if TARGET_OS_MAC
  39. Str255                        gAppName = "\pMakeEffectMovie";        // the name of this application
  40. AEEventHandlerUPP            gHandleOpenAppAEUPP;                // UPPs for our Apple event handlers
  41. AEEventHandlerUPP            gHandleOpenDocAEUPP;
  42. AEEventHandlerUPP            gHandlePrintDocAEUPP;
  43. AEEventHandlerUPP            gHandleQuitAppAEUPP;
  44. #endif
  45.  
  46. // global variables for Windows code
  47. #if TARGET_OS_WIN32
  48. extern HWND                    ghWnd;                                // the MDI frame window; this window has the menu bar
  49. extern int                    gNumWindowsOpen;
  50. extern Boolean                gShuttingDown;
  51. extern LPSTR                gCmdLine;
  52. #endif
  53.  
  54. long                        gMaxMilliSecToUse = 0L;    
  55.     
  56. // external variables
  57. extern Boolean                gAppInForeground;                    // is our application in the foreground?    
  58. extern QTParameterDialog    gEffectsDialog;
  59. extern Boolean                gCopyMovieMedia;                    // should we copy the movie media into the new effects movie?
  60.  
  61.  
  62. //////////
  63. //
  64. // InitApplication
  65. // Do any application-specific initialization.
  66. //
  67. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  68. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  69. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  70. //
  71. //////////
  72.  
  73. void InitApplication (UInt32 theStartPhase)
  74. {
  75.     // ***do any start-up activities that should occur before the MDI frame window is created
  76.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  77.     
  78.         // check to make sure that QuickTime video effects are available;
  79.         // we depend on these features  
  80.         if (!QTUtils_HasQuickTimeVideoEffects())
  81.             QuitFramework();
  82.         
  83. #if TARGET_OS_MAC
  84.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  85.         InstallAppleEventHandlers();
  86. #endif
  87.     }    // end of kInitAppPhase_BeforeCreateFrameWindow
  88. }
  89.  
  90.  
  91. //////////
  92. //
  93. // StopApplication
  94. // Do any application-specific shut-down.
  95. //
  96. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  97. // *before* any open movie windows are destroyed or *after*.
  98. //
  99. //////////
  100.  
  101. void StopApplication (UInt32 theStopPhase)
  102. {
  103.     // ***do any shut-down activities that should occur after the movie windows are destroyed
  104.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  105. #if TARGET_OS_MAC
  106.         // dispose of routine descriptors for Apple event handlers
  107.         DisposeRoutineDescriptor(gHandleOpenAppAEUPP);
  108.         DisposeRoutineDescriptor(gHandleOpenDocAEUPP);
  109.         DisposeRoutineDescriptor(gHandlePrintDocAEUPP);
  110.         DisposeRoutineDescriptor(gHandleQuitAppAEUPP);
  111. #endif
  112.     }    // end of kStopAppPhase_AfterDestroyWindows
  113. }
  114.  
  115.  
  116. //////////
  117. //
  118. // DoIdle
  119. // Do any processing that can/should occur at idle time.
  120. //
  121. //////////
  122.  
  123. void DoIdle (WindowReference theWindow)
  124. {
  125.     WindowObject         myWindowObject = NULL;
  126.     GrafPtr             mySavedPort;
  127.     
  128.     GetPort(&mySavedPort);
  129.     MacSetPort(GetPortFromWindowReference(theWindow));
  130.     
  131.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  132.     if (myWindowObject != NULL) {
  133.         MovieController        myMC = NULL;
  134.     
  135.         myMC = (**myWindowObject).fController;
  136.         if (myMC != NULL) {
  137.  
  138. #if TARGET_OS_MAC
  139.             // restore the cursor to the arrow
  140.             // if it's outside the front movie window or outside the window's visible region
  141.             if (theWindow == GetFrontMovieWindow()) {
  142.                 Rect    myRect;
  143.                 Point    myPoint;
  144.                 
  145.                 GetMouse(&myPoint);
  146.                 MCGetControllerBoundsRect(myMC, &myRect);
  147.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, GetPortFromWindowReference(theWindow)->visRgn))
  148.                     MacSetCursor(&qd.arrow);
  149.             }
  150. #endif    // TARGET_OS_MAC
  151.         }
  152.     }
  153.     
  154.     // @@@INSERT APPLICATION-SPECIFIC IDLE-TIME FUNCTIONALITY HERE
  155.     
  156.     MacSetPort(mySavedPort);
  157. }
  158.  
  159.  
  160. //////////
  161. //
  162. // DoUpdateWindow
  163. // Update the specified window.
  164. //
  165. //////////
  166.  
  167. void DoUpdateWindow (WindowReference theWindow, Rect *theRefreshArea)
  168. {
  169.     GrafPtr             mySavedPort;
  170.     
  171.     GetPort(&mySavedPort);
  172.     MacSetPort(GetPortFromWindowReference(theWindow));
  173.     
  174.     BeginUpdate(theWindow);
  175.     
  176.     // draw the movie controller and its movie
  177.     MCDoAction(GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  178.     
  179.     EndUpdate(theWindow);
  180.     MacSetPort(mySavedPort);
  181. }
  182.  
  183.  
  184. //////////
  185. //
  186. // HandleContentClick
  187. // Handle mouse button clicks in the specified window.
  188. //
  189. //////////
  190.  
  191. void HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  192. {
  193. #pragma unused(theEvent)
  194.  
  195.     GrafPtr             mySavedPort;
  196.     
  197.     GetPort(&mySavedPort);
  198.     MacSetPort(GetPortFromWindowReference(theWindow));
  199.     
  200.     // @@@INSERT APPLICATION-SPECIFIC CONTENT CLICKING FUNCTIONALITY HERE
  201.  
  202.     MacSetPort(mySavedPort);
  203. }
  204.  
  205.  
  206. //////////
  207. //
  208. // HandleApplicationKeyPress
  209. // Handle application-specific key presses.
  210. // Returns true if the key press was handled, false otherwise.
  211. //
  212. //////////
  213.  
  214. Boolean HandleApplicationKeyPress (char theCharCode)
  215. {
  216.     Boolean        isHandled = true;
  217.     
  218.     switch (theCharCode) {
  219.     
  220.         // @@@HANDLE APPLICATION-SPECIFIC KEY PRESSES HERE
  221.  
  222.         default:
  223.             isHandled = false;
  224.             break;
  225.     }
  226.  
  227.     return(isHandled);
  228. }
  229.  
  230.  
  231. #if TARGET_OS_MAC
  232. //////////
  233. //
  234. // CreateMovieWindow
  235. // Create a window to display a movie in.
  236. //
  237. //////////
  238.  
  239. WindowRef CreateMovieWindow (Rect *theRect, Str255 theTitle)
  240. {
  241.     WindowRef            myWindow;
  242.         
  243.     myWindow = NewCWindow(NULL, theRect, theTitle, false, noGrowDocProc, (WindowPtr)-1L, true, 0);
  244.     return(myWindow);
  245. }
  246. #endif
  247.  
  248.  
  249. //////////
  250. //
  251. // HandleApplicationMenu
  252. // Handle selections in the application's menus.
  253. //
  254. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  255. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window proc.
  256. // When called from MacOS, theMenuItem is constructed like this:
  257. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  258. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  259. // In this way, we can simplify the menu-handling code. There are, however, some limitations,
  260. // mainly that the menu item identifiers on Windows must be derived from the Mac values. 
  261. //
  262. //////////
  263.  
  264. void HandleApplicationMenu (UInt16 theMenuItem)
  265. {
  266.     switch (theMenuItem) {
  267.         case IDM_MAKE_EFFECT_MOVIE:
  268.             // ask the user for some movies and an effect,
  269.             // but only if the effects dialog isn't showing already
  270.             if (gEffectsDialog == 0L)
  271.                 QTEffects_PromptUserForFilesAndMakeEffect();
  272.             break;
  273.  
  274.         case IDM_MAKE_STANDALONE_MOVIE:
  275.             gCopyMovieMedia = true;
  276.             break;
  277.  
  278.         case IDM_MAKE_REFERENCED_MOVIE:
  279.             gCopyMovieMedia = false;
  280.             break;
  281.  
  282.         default:
  283.             break;
  284.     } // switch (theMenuItem)
  285. }
  286.  
  287.  
  288. //////////
  289. //
  290. // AdjustApplicationMenus
  291. // Adjust state of items in the application's menus.
  292. //
  293. // Currently, the Mac application has only one app-specific menu ("Test"); you could change that.
  294. //
  295. //////////
  296.  
  297. void AdjustApplicationMenus (WindowReference theWindow, MenuReference theMenu)
  298. {
  299. #pragma unused(theWindow)
  300.     MenuReference            myMenu;
  301.     
  302. #if TARGET_OS_WIN32
  303.     myMenu = theMenu;
  304. #elif TARGET_OS_MAC
  305.     myMenu = GetMenuHandle(kTestMenu);
  306. #endif
  307.     
  308.     // we don't allow creating new files here...
  309. #if TARGET_OS_MAC
  310.     SetMenuItemState(GetMenuHandle(mFile), iNew, kDisableMenuItem);
  311. #endif
  312.     
  313.     // if effects dialog is already open, don't allow user to select more files
  314.     if (gEffectsDialog != 0)
  315.         SetMenuItemState(myMenu, IDM_MAKE_EFFECT_MOVIE, kDisableMenuItem);
  316.     else
  317.         SetMenuItemState(myMenu, IDM_MAKE_EFFECT_MOVIE, kEnableMenuItem);
  318.     
  319.     // check the current media-copying selection    
  320.     SetMenuItemCheck(myMenu, IDM_MAKE_STANDALONE_MOVIE, gCopyMovieMedia == true);
  321.     SetMenuItemCheck(myMenu, IDM_MAKE_REFERENCED_MOVIE, gCopyMovieMedia == false);
  322. }
  323.  
  324.  
  325. //////////
  326. //
  327. // DoApplicationEventLoopAction
  328. // Perform any application-specific event loop actions.
  329. //
  330. // Return true to indicate that we've completely handled the event here, false otherwise.
  331. //
  332. //////////
  333.  
  334. Boolean DoApplicationEventLoopAction (EventRecord *theEvent)
  335. {
  336.     Boolean        isHandled = false;
  337.     
  338.     // see if the event is meant for the effects parameter dialog box
  339.     if (gEffectsDialog != 0L)
  340.         isHandled = QTEffects_HandleEffectsDialogEvents(theEvent, 0);
  341.  
  342.     return(isHandled);
  343. }
  344.  
  345.  
  346. //////////
  347. //
  348. // AddControllerFunctionality
  349. // Configure the movie controller.
  350. //
  351. //////////
  352.  
  353. void AddControllerFunctionality (MovieController theMC)
  354. {
  355.     long            myControllerFlags;
  356.     
  357.     // CLUT table use    
  358.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  359.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  360.  
  361.     // enable keyboard event handling    
  362.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  363.     
  364.     // disable drag support
  365.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  366. }
  367.  
  368.  
  369. //////////
  370. //
  371. // InitApplicationWindowObject
  372. // Do any application-specific initialization of the window object.
  373. //
  374. //////////
  375.  
  376. void InitApplicationWindowObject (WindowObject theWindowObject)
  377. {
  378. #pragma unused(theWindowObject)
  379. }
  380.  
  381.  
  382. //////////
  383. //
  384. // RemoveApplicationWindowObject
  385. // Do any application-specific clean-up of the window object.
  386. //
  387. //////////
  388.  
  389. void RemoveApplicationWindowObject (WindowObject theWindowObject)
  390. {
  391. #pragma unused(theWindowObject)
  392.     // DoDestroyMovieWindow in MacFramework.c or MovieWndProc in WinFramework.c
  393.     // releases the window object itself
  394. }
  395.  
  396.  
  397. //////////
  398. //
  399. // ApplicationMCActionFilterProc 
  400. // Intercept some mc actions for the movie controller.
  401. //
  402. // NOTE: The theRefCon parameter is a handle to a window object record.
  403. //
  404. //////////
  405.  
  406. PASCAL_RTN Boolean ApplicationMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  407. {
  408. #pragma unused(theMC, theParams)
  409.  
  410.     Boolean                isHandled = false;
  411.     WindowObject        myWindowObject = NULL;
  412.     
  413.     myWindowObject = (WindowObject)theRefCon;
  414.     if (myWindowObject == NULL)
  415.         return(isHandled);
  416.         
  417.     switch (theAction) {
  418.     
  419.         // handle window resizing
  420.         case mcActionControllerSizeChanged:
  421.             SizeWindowToMovie(myWindowObject);
  422.             break;
  423.  
  424.         // handle idle events
  425.         case mcActionIdle:
  426.             DoIdle((**myWindowObject).fWindow);
  427.             break;
  428.             
  429.         default:
  430.             break;
  431.             
  432.     }    // switch (theAction)
  433.     
  434.     return(isHandled);    
  435. }
  436.  
  437.  
  438. #if TARGET_OS_MAC
  439. //////////
  440. //
  441. // InstallAppleEventHandlers 
  442. // Install handlers for Apple events.
  443. //
  444. //////////
  445.  
  446. void InstallAppleEventHandlers (void)
  447. {
  448.     long        myAttrs;
  449.     OSErr        myErr = noErr;
  450.     
  451.     // see whether the Apple Event Manager is available in the present operating environment;
  452.     // if it is, install handlers for the four required Apple events
  453.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  454.     if (myErr == noErr) {
  455.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  456.             // create routine descriptors for the Apple event handlers
  457.             gHandleOpenAppAEUPP = NewAEEventHandlerProc(HandleOpenApplicationAppleEvent);
  458.             gHandleOpenDocAEUPP = NewAEEventHandlerProc(HandleOpenDocumentAppleEvent);
  459.             gHandlePrintDocAEUPP = NewAEEventHandlerProc(HandlePrintDocumentAppleEvent);
  460.             gHandleQuitAppAEUPP = NewAEEventHandlerProc(HandleQuitApplicationAppleEvent);
  461.             
  462.             // install the handlers
  463.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  464.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  465.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  466.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  467.         }
  468.     }
  469. }
  470.         
  471.         
  472. //////////
  473. //
  474. // HandleOpenApplicationAppleEvent 
  475. // Handle the open-application Apple event.
  476. //
  477. //////////
  478.  
  479. pascal OSErr HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  480. {
  481. #pragma unused(theMessage, theReply, theRefcon)
  482.  
  483.     // we don't need to do anything special when opening the application
  484.     return(noErr);
  485. }
  486.  
  487.  
  488. //////////
  489. //
  490. // HandleOpenDocumentAppleEvent 
  491. // Handle the open-document Apple event. This is based on Inside Macintosh: IAC, pp. 4-15f.
  492. //
  493. //////////
  494.  
  495. pascal OSErr HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  496. {
  497. #pragma unused(theReply, theRefcon)
  498.  
  499.     long            myIndex;
  500.     long            myItemsInList;
  501.     AEKeyword        myKeyWd;
  502.     OSErr            myIgnoreErr;
  503.     AEDescList          myDocList;
  504.     long            myActualSize;
  505.     DescType        myTypeCode;
  506.     FSSpec            myFSSpec;
  507.     FSSpec            myFSSpecList[kMaxNumSources];
  508.     UInt16            myFSSpecCount = 0;
  509.     OSErr            myErr = noErr;
  510.     
  511.     // get the direct parameter and put it into myDocList
  512.     myDocList.dataHandle = NULL;
  513.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  514.     
  515.     // count the descriptor records in the list
  516.     if (myErr == noErr)
  517.         myErr = AECountItems(&myDocList, &myItemsInList);
  518.     else
  519.         myItemsInList = 0;
  520.     
  521.     // open each specified file
  522.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  523.         if (myErr == noErr) {
  524.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  525.             if ((myErr == noErr) && (myFSSpecCount < kMaxNumSources)) {
  526.                 myFSSpecList[myFSSpecCount] = myFSSpec;
  527.                 myFSSpecCount++;
  528.             }
  529.         }
  530.  
  531.     if (myDocList.dataHandle)
  532.         myIgnoreErr = AEDisposeDesc(&myDocList);
  533.     
  534.     if (myErr == noErr)
  535.         myErr = QTEffects_DisplayDialogForSources(myFSSpecList, myFSSpecCount);
  536.     
  537.     // make sure we open the document in the foreground        
  538.     gAppInForeground = true;
  539.     return(myErr);
  540. }
  541.  
  542.  
  543. //////////
  544. //
  545. // HandlePrintDocumentAppleEvent 
  546. // Handle the print-document Apple event.
  547. //
  548. //////////
  549.  
  550. pascal OSErr HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  551. {
  552. #pragma unused(theMessage, theReply, theRefcon)
  553.     QuitFramework();
  554.     return(errAEEventFailed);
  555. }
  556.  
  557.  
  558. //////////
  559. //
  560. // HandleQuitApplicationAppleEvent 
  561. // Handle the quit-application Apple event.
  562. //
  563. //////////
  564.  
  565. pascal OSErr HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  566. {
  567. #pragma unused(theMessage, theReply, theRefcon)
  568.  
  569.     // close down the entire framework and application
  570.     QuitFramework();
  571.     return(noErr);
  572. }
  573. #endif    // TARGET_OS_MAC
  574.  
  575.  
  576.